﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Diagnostics;


namespace ERPStore.SvcHost
{
	[RunInstaller(true)]
	public partial class ProjectInstaller : System.Configuration.Install.Installer
	{
		string m_ServiceName = null;

		public ProjectInstaller()
		{
			InitializeComponent();

			var exePath = System.IO.Path.Combine(Environment.CurrentDirectory, "erpstoresvchost.exe");
			System.Diagnostics.Trace.WriteLine(exePath);
			var config = System.Configuration.ConfigurationManager.OpenExeConfiguration(exePath);
			m_ServiceName = "ERPStoreSvcHost";
			if (config.AppSettings.Settings["erpstore.serviceName"] != null)
			{
				m_ServiceName = config.AppSettings.Settings["erpstore.serviceName"].Value;
			}
			Console.WriteLine("ServiceName : {0}", m_ServiceName);
			SetServiceName(m_ServiceName);

		}

		protected override void OnBeforeInstall(IDictionary savedState)
		{
			try
			{
				AddUrlAcl();
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.ToString());
			}

			string serviceName = m_ServiceName; //  this.ServiceName(savedState);
			Console.WriteLine("ServiceName : {0}", serviceName);
			savedState["ServiceName"] = serviceName;
			SetServiceName(serviceName);
			Console.WriteLine(serviceName);
			base.OnBeforeInstall(savedState);
		}

		protected override void OnBeforeUninstall(IDictionary savedState)
		{
			try
			{
				RemoveUrlAcl();
			}
			catch (Exception ex)
			{
				System.Diagnostics.Trace.TraceError(ex.ToString());
			}
			this.SetServiceName(this.ServiceName(savedState));
			base.OnBeforeUninstall(savedState);
		}

		private void SetServiceName(string serviceName)
		{
			this.ERPStoreServiceInstaller.DisplayName = serviceName;
			this.ERPStoreServiceInstaller.ServiceName = serviceName;
		}

		private string ServiceName(IDictionary savedState)
		{
			if (base.Context.Parameters.ContainsKey("ServiceName"))
			{
				return base.Context.Parameters["ServiceName"];
			}
			if (savedState.Contains("ServiceName"))
			{
				return savedState["ServiceName"].ToString();
			}
			return "ERPStoreSvcHost";
		}

		private void RemoveUrlAcl()
		{
			var webapiAddress = System.Configuration.ConfigurationManager.AppSettings["webapiAddress"] ?? "http://localhost:9080";
			var address = new Uri(webapiAddress);
			var parameters = string.Format("http delete urlacl url=http//+:{0}/", address.Port);
			ExecuteNetsh(parameters);
		}

		private void AddUrlAcl()
		{
			RemoveUrlAcl();
			string networkServiceAccount = new System.Security.Principal.SecurityIdentifier(
					"S-1-5-20").Translate(typeof(System.Security.Principal.NTAccount)).ToString();

			var webapiAddress = System.Configuration.ConfigurationManager.AppSettings["webapiAddress"] ?? "http://localhost:9080";
			var address = new Uri(webapiAddress);
			var parameters = string.Format("http add urlacl url=http//+:{0}/ user=\"{1}\"", address.Port, networkServiceAccount);
			ExecuteNetsh(parameters);
		}

		private void ExecuteNetsh(string parameters)
		{
			Console.WriteLine("netsh " + parameters);

			var psi = new ProcessStartInfo("netsh", parameters);
			psi.CreateNoWindow = true;
			psi.WindowStyle = ProcessWindowStyle.Hidden;
			psi.ErrorDialog = false;
			psi.UseShellExecute = false;
			psi.RedirectStandardError = true;
			psi.RedirectStandardOutput = true;

			var p = Process.Start(psi);
			var reader = p.StandardOutput;
			var content = reader.ReadToEnd();

			Console.WriteLine("netsh execution result : " + content);
		}
	}
}
